package http

import (
	"bytes"
	"encoding/json"
	"gitee.com/yysf_xin/go-common/tools"
	"gitee.com/yysf_xin/go-common/tools/template"
	"gitee.com/yysf_xin/go-notifier"
	"gitee.com/yysf_xin/go-notifier/model"
	"gitee.com/yysf_xin/go-notifier/oauth2"
	"io"
	"net/http"
	"strings"
)

type Config struct {
	Header http.Header
	Method string
	Oauth2 *oauth2.Config
}

type MsgService struct {
	Supplier *model.Supplier
	Tr       http.RoundTripper
	Http     http.Client
	Cfg      *Config
}

func New(n *notifier.Notifier, supplier *model.Supplier) (svr notifier.MsgService, err error) {
	s := &MsgService{
		Supplier: supplier,
		Tr:       n.Tr,
	}
	if supplier.Config != "" {
		var cfg = new(Config)
		err = json.NewDecoder(strings.NewReader(supplier.Config)).Decode(cfg)
		if err != nil {
			tools.Log.Println(err)
			return
		}
		if cfg.Oauth2 != nil {
			s.Tr = oauth2.New(cfg.Oauth2, template.MapObj(supplier, cfg), n.Tr)
		}
		s.Cfg = cfg
	}
	svr = s
	return
}
func (s *MsgService) Init(v *model.Template, data any, opt *notifier.Option) (any, error) {
	return data, nil
}

func (s *MsgService) DoSend(v *model.Template, param any, opt *notifier.Option) {
	url := s.Supplier.Url
	if v.Url != "" {
		url = v.Url
	}
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(tools.StringToBytes(v.Content)))
	if err != nil {
		tools.Log.Println(err)
		return
	}

	if s.Cfg != nil {
		if s.Cfg.Header != nil {
			req.Header = s.Cfg.Header
		}
		if s.Cfg.Method != "" {
			req.Method = s.Cfg.Method
		}
	}
	ct := req.Header.Get("Content-Type")
	if ct == "" {
		req.Header.Set("Content-Type", "application/json")
	}
	var resp *http.Response
	resp, err = s.Tr.RoundTrip(req)
	if resp != nil && resp.Body != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		tools.Log.Println(err)
		return
	}
	if resp != nil && resp.Body != nil {
		d, _ := io.ReadAll(resp.Body)
		if d != nil {
			tools.Log.Println(resp.StatusCode, tools.BytesToString(d))
		}
	}
}

func init() {
	notifier.RegService("http", New)
}
